import type { ComponentStyleIdType } from '../../types/interfaces'
import type { TextInputProps } from './types'
import { UIComponent } from '../../lib/abstract'
import { ComponentStyleId, logger } from '../../types/constants'
import { styles } from './styles'
import { DEFAULT_TEXT_INPUT_PROPS } from './types'

export class TextInput extends UIComponent<TextInputProps> {
  id: string = 'text_input'
  readonly description: string = '文本输入框'
  readonly styleId: string = ComponentStyleId[this.name]
  element: JQuery<HTMLElement> | undefined = undefined

  get name(): ComponentStyleIdType {
    return 'TextInput'
  }

  get className(): string {
    return 'custom-text-input'
  }

  constructor(props: TextInputProps) {
    super({
      ...DEFAULT_TEXT_INPUT_PROPS,
      ...props,
    })

    // 注册样式
    this.registerStyles()
  }

  ELEMENT_SELECTORS = {
    input: { selector: `#${this.props.id}`, dynamic: false, unique: true },
  }

  public render(): string {
    const { id, label, value, placeholder, autocomplete, type, rows, accept, className, inputClassName } = this.props

    if (type === 'textarea') {
      return `
        ${label ? `<label for="${id}">${label}</label>` : ''}
        <div class="custom-text-input ${className}">
          <textarea 
            id="${id}" 
            class="${inputClassName}"
            rows="${rows}" 
            placeholder="${placeholder || ''}"
            autocomplete="${autocomplete || 'off'}"
            title=""
          >${value}</textarea>
        </div>
      `
    }

    if (type === 'file') {
      return `
        ${label ? `<label for="${id}">${label}</label>` : ''}
        <div class="custom-text-input ${className}">
          <input 
            id="${id}" 
            class="${inputClassName}"
            type="file" 
            accept="${accept}" 
            title=""
            ${value ? 'data-has-file="true"' : ''}
          >
        </div>
      `
    }

    return `
      ${label ? `<label for="${id}">${label}</label>` : ''}
      <div class="custom-text-input ${className}">
        <input 
          id="${id}" 
          class="${inputClassName}"
          type="${type}" 
          value="${value}" 
          title=""
          placeholder="${placeholder || ''}"
          autocomplete="${autocomplete || 'off'}"
        >
      </div>
    `
  }

  bindEvents(): void {
    const $input = this.getElement('input')
    if (!$input || !$input.length || !this.props.onChange)
      return

    if (this.props.type === 'file') {
      $input.on('change', (e) => {
        const files = (e.target as HTMLInputElement).files
        if (files) {
          this.props.onChange?.(files)
        }
      })
    }
    else {
      $input
        ?.off('blur keydown') // 先解绑避免重复绑定
        ?.on('blur', (e: JQuery.BlurEvent) => this.handleTextChange(e))
        ?.on('keydown', (e: JQuery.KeyDownEvent) => {
          const $element = $(e.currentTarget)

          if (e.key === 'Enter') {
            // 判断是否按下了 Shift 键
            if (e.shiftKey) {
              // Shift+Enter: 插入换行
              return true // 允许默认行为（换行）
            }
            else {
              // 纯 Enter: 触发表单提交
              e.preventDefault() // 阻止默认换行行为
              this.handleTextChange(e)
              $element.trigger('blur')
            }
          }
        })
    }
  }

  handleTextChange(e: JQuery.BlurEvent | JQuery.KeyDownEvent): void {
    const $element = $(e.currentTarget as HTMLInputElement)
    this.props.onChange?.($element.val() as string)
  }

  getStyles(): string {
    return styles()
  }

  reset(): void {
    if (!this.element || !this.element.length) {
      logger.warn(`[${this.name}] 找不到所属元素`)
    }

    // 重置文本输入
    this.getElement('input')?.val('').trigger('blur')
  }
}
